(堆)内存释放
- [ ] 不能销毁的情况:堆内存地址被外界变量引用时
- 对象数据类型或者函数数据类型在定义时,会开辟一个堆内存,这个堆内存有一个引用的地址,如果外面有变量接收这个地址,这个内存就被占用了,因此不能销毁;
- [ ] 把引用内存地址的变量
=null
来销毁- 当内存地址不被引用了,那么浏览器会在空闲时销毁这个堆内存;
-
- 以下面代码为例1234567//对象或者函数类型(obj1)在定义时,开辟一个堆内存var obj1={name:"张三"};//(obj1的堆地址)被(obj2)引用var obj2=obj1;//通过(=null)来销毁obj1=null;obj2=null;//如果只清除obj2,那么obj1内存仍存在,视浏览器清除机制而定;
其图形分析为图20
对于内存谷歌、IE、火狐不同浏览器的处理技巧谷歌
:定时主动清除当前页面中不被占用的内存;IE、火狐
:计数器原理,当被占用数=0时,清除该内存;
- 当计数计晕了时,产生内存泄漏问题
(栈)作用域销毁
全局作用域(只有页面关闭才会销毁)
私有作用域(只有函数执行才会产生私有作用域)
|
|
(1)一般情况下,函数执行产生新的私有作用域,执行完毕会主动释放和销毁;
(2)特殊情况下,当前私有作用域部分内存被作用域以外的占用,则当前内存不能销毁,(分下面三种情况)
[x]
1、
(不销毁)–函数执行返回引用数据类型、且在函数外被接收(原理就是堆内存被占有,其地盘也不能销毁)
以下面代码为例
12345678var num=12;function fn(){var num=120;return function(){…………};}var f=fn();////fn执行时形成的私有作用域不销毁
图形分析21
[x]
2、
(不销毁)- -在一个私有作用于下给DOM元素绑定事件,这种情况一般不销毁私有作用域以下面代码为例
12345var oDiv=document.getElementById("div");~function (){oDiv.onclick=function(){}}();//自执行函数形成的私有作用域不销毁
图形分析22
[x]
3、
(不立即销毁) fn()()–fn返回的函数没被占用,但是还需要执行一次,所以暂时不销毁,待返回的值执行完后浏览器会在空闲的时候把它销毁;以下面代码为例
123456function fn(){var num=100;return function(){};};fn()();//先执行fn(),返回一个对应的内存地址,然后紧接着执行返回的小函数
作用域销毁实战题
小知识点1234var i=5;//每运算一小步,i的值都会变alert(2+(i++)+(++i)+(++i)+(i++));//-->30;//运算完2+(i++)后i=6
以下面代码为例1
123456789101112131415161718function fn(){var i=10;return function(n){console.log(n+(++i));}}//函数执行每次跟每次都没关系var f=fn();//f的上级作用域是fn()A作用域--不销毁f(10); //10+11=21;f(20); //20+12=32;//此时fn()()的上级作用域是fn()B作用域--在fn()()执行前暂时不销毁fn()(10); //10+11=21//此时fn()()的上级作用域是fn()C作用域--在fn()()执行前暂时不销毁fn()(20); //20+11=31
分析图形23
以下面代码为例2
12345678910function fn(i){return function(n){console.log(n+(i++));}}var f=fn(13); //i=13f(12); //i=13 12+13=25 i=14f(14); //i=14 14+14=28 i=15fn(15)(12); //i=15 12+15=27 i=16fn(16)(13); //i=16 13+16=29 i=17思考题:用闭包作用域的方式,实现选项卡循环绑定事件的处理